package com.wallellen.android.currencies;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.AssetManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Properties;


public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
    private static final String FOR = "FOR_CURRENCY";
    private static final String HOM = "HOM_CURRENCY";

    //used to fetch the 'rates' json object from openexchangerates.org
    public static final String URL_BASE = "https://openexchangerates.org/api/latest.json?app_id=";
    public static final String RATES = "rates";
    //used to format data from openexchangerates.org
    private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#,##0.00000");

    private Button mCalcButton;
    private TextView mConvertedTextView;
    private EditText mAmountEditText;
    private Spinner mForSpinner;
    private Spinner mHomSpinner;
    private String[] mCurrencies;

    // this will contains my developer key
    private String mKey;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ActionBar actionBar = getSupportActionBar();
        actionBar.setHomeButtonEnabled(true);
        actionBar.setDisplayShowHomeEnabled(true);
        actionBar.setIcon(R.mipmap.ic_launcher);


        mCalcButton = (Button) findViewById(R.id.btn_calc);
        mConvertedTextView = (TextView) findViewById(R.id.text_converted);
        mAmountEditText = (EditText) findViewById(R.id.edt_amount);
        mForSpinner = (Spinner) findViewById(R.id.spn_for);
        mHomSpinner = (Spinner) findViewById(R.id.spn_home);

        ArrayList<String> serializables = (ArrayList<String>) getIntent().getSerializableExtra(SplashActivity.KEY_ARRAYLIST);
        Collections.sort(serializables);
        mCurrencies = serializables.toArray(new String[0]);

        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(
                this, R.layout.spinner_closed, mCurrencies
        );

        arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        mForSpinner.setAdapter(arrayAdapter);
        mHomSpinner.setAdapter(arrayAdapter);

        mForSpinner.setOnItemSelectedListener(this);
        mHomSpinner.setOnItemSelectedListener(this);

        if (savedInstanceState == null && PrefsMgr.getString(this, FOR) == null && PrefsMgr.getString(this, HOM) == null) {
            mForSpinner.setSelection(findPositionByGivenCode("CNY", mCurrencies));
            mHomSpinner.setSelection(findPositionByGivenCode("USD", mCurrencies));

            PrefsMgr.setString(this, FOR, "CNY");
            PrefsMgr.setString(this, HOM, "USD");
        } else {
            mForSpinner.setSelection(findPositionByGivenCode(PrefsMgr.getString(this, FOR), mCurrencies));
            mHomSpinner.setSelection(findPositionByGivenCode(PrefsMgr.getString(this, HOM), mCurrencies));
        }

        mCalcButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isNumberic(mAmountEditText.getText().toString())) {
                    new CurrencyConverterTask().execute(URL_BASE + mKey);
                } else {
                    Toast.makeText(MainActivity.this, mAmountEditText.getText().toString() + " is not a valid double", Toast.LENGTH_LONG);
                }
            }
        });

        mKey = getKey("open_key");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
//        if (id == R.id.action_settings) {
//            return true;
//        }

        switch (id) {
            case R.id.mnu_codes:
                launchBrowser(SplashActivity.URL);
                break;
            case R.id.mnu_invert:
                invertCurrencies();
                break;
            case R.id.mnu_exit:
                finish();
                break;
        }

        return super.onOptionsItemSelected(item);
    }

    private static int findPositionByGivenCode(String code, String[] currencies) {
        for (int i = 0; i < currencies.length; i++) {
            if (extractCodeFromCurrency(currencies[i]).equalsIgnoreCase(code)) {
                return i;
            }
        }

        return 0;
    }

    private static String extractCodeFromCurrency(String currency) {
        return currency.substring(0, 3);
    }

    private boolean isOnline() {
        ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netWorkInfo = manager.getActiveNetworkInfo();

        return netWorkInfo != null && netWorkInfo.isConnectedOrConnecting();
    }

    private void launchBrowser(String strUri) {
        if (!isOnline()) {
            return;
        }

        Uri uri = Uri.parse(strUri);
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        startActivity(intent);
    }

    private void invertCurrencies() {
        int nFor = mForSpinner.getSelectedItemPosition();
        int nHom = mHomSpinner.getSelectedItemPosition();

        mForSpinner.setSelection(nHom);
        mHomSpinner.setSelection(nFor);

        mConvertedTextView.setText("");
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        switch (parent.getId()) {
            case R.id.spn_for:
                PrefsMgr.setString(this, FOR, extractCodeFromCurrency((String) mForSpinner.getSelectedItem()));
                break;
            case R.id.spn_home:
                PrefsMgr.setString(this, HOM, extractCodeFromCurrency((String) mHomSpinner.getSelectedItem()));
                break;
            default:
                break;
        }

        mConvertedTextView.setText("");
        PrefsMgr.setString(this, FOR, extractCodeFromCurrency((String) mForSpinner.getSelectedItem()));
        PrefsMgr.setString(this, HOM, extractCodeFromCurrency((String) mHomSpinner.getSelectedItem()));
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }

    public String getKey(String key) {
        AssetManager assets = this.getResources().getAssets();
        Properties props = new Properties();

        try {
            InputStream is = assets.open("keys.properties");
            props.load(is);
        } catch (IOException e) {
            Log.e(this.getClass().getName(), e.getMessage(), e);
        }

        return props.getProperty(key);
    }

    private class CurrencyConverterTask extends AsyncTask<String, Void, JSONObject> {
        private ProgressDialog progressDialog;

        @Override
        protected JSONObject doInBackground(String... params) {
            Log.d(this.getClass().getName(), "do in background");
            return new JSONParser().getJSONFromUrl(params[0]);
        }

        @Override
        protected void onPreExecute() {
            //super.onPreExecute();
            Log.d(this.getClass().getName(), "pre execute");
            progressDialog = new ProgressDialog(MainActivity.this);
            progressDialog.setTitle("Calculating Result ...");
            progressDialog.setMessage("One moment please ...");
            progressDialog.setCancelable(false);

            progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    CurrencyConverterTask.this.cancel(true);
                    progressDialog.dismiss();
                }
            });

            progressDialog.show();
        }

        @Override
        protected void onPostExecute(JSONObject jsonObject) {
            //super.onPostExecute(jsonObject);
            Log.d(this.getClass().getName(), "post execute");
            double dCalculated = 0.0;
            String strForCode = extractCodeFromCurrency(mCurrencies[mForSpinner.getSelectedItemPosition()]);
            String strHomCode = extractCodeFromCurrency(mCurrencies[mHomSpinner.getSelectedItemPosition()]);
            String strAmount = mAmountEditText.getText().toString();

            try {
                if (jsonObject == null) {
                    throw new JSONException(" no data available");
                }

                Log.d(getClass().getName(), jsonObject.toString());
                JSONObject jsonRates = jsonObject.getJSONObject(RATES);
                if ("USD".equalsIgnoreCase(strForCode)) {
                    dCalculated = Double.parseDouble(strAmount) * jsonRates.getDouble(strHomCode);
                } else if ("USD".equalsIgnoreCase(strHomCode)) {
                    dCalculated = Double.parseDouble(strAmount) / jsonRates.getDouble(strForCode);
                } else {
                    dCalculated = Double.parseDouble(strAmount) * jsonRates.getDouble(strHomCode) / jsonRates.getDouble(strForCode);
                }

                mConvertedTextView.setText(DECIMAL_FORMAT.format(dCalculated) + " " + strHomCode);
            } catch (JSONException e) {
//                e.printStackTrace();
                Toast.makeText(MainActivity.this, "There's bean a json exception: " + e.getMessage(), Toast.LENGTH_LONG).show();
                Log.e(this.getClass().getName(), e.getMessage(), e);
                mConvertedTextView.setText("");
            } finally {
                progressDialog.dismiss();

                if (currencyConverterTaskCallback != null) {
                    currencyConverterTaskCallback.executionDone();
                } 
            }
        }
    }

    private boolean isNumberic(String str) {
        try {
            Double.parseDouble(str);
        } catch (NumberFormatException ex) {
            return false;
        }

        return true;
    }

    private CurrencyConverterTaskCallback currencyConverterTaskCallback;

    public interface CurrencyConverterTaskCallback {
        void executionDone();
    }

    public void setCurrencyConverterTaskCallback(CurrencyConverterTaskCallback callback) {
        this.currencyConverterTaskCallback = callback;
    }
}
